package edu.whu.rose.clock.ssql.util;

public class SequentialIntMap {

	private int[] keys;
	private int[][] values;
	private int size = 10;
	private int capacity = 0;
	private int vSize = 5;
	private int[] vSizes;
	private int[] vCapacity;
	
	public SequentialIntMap() {
		keys = new int[size];
		vSizes = new int[size];
		for (int i = 0; i < size; i++) {
			vSizes[i] = vSize;
		}
		values = new int[size][];
		vCapacity = new int[size];
	}
	
	public SequentialIntMap(int size) {
		this.size = size;
		keys = new int[size];
		vSizes = new int[size];
		for (int i = 0; i < size; i++) {
			vSizes[i] = vSize;
		}
		values = new int[size][];
		vCapacity = new int[size];
	}
	
	public void insert(int key, int[] value, int vc, int vs) {
		if (capacity == size) {
			size = 2 * size;
			int[] temp1 = keys;
			keys = new int[size];
			int[][] temp2 = values;
			values = new int[size][];
			int[] temp3 = vSizes;
			vSizes = new int[size];
			int[] temp4 = vCapacity;
			vCapacity = new int[size];
			for (int i = 0; i < temp1.length; i++) {
				keys[i] = temp1[i];
				values[i] = temp2[i];
				vSizes[i] = temp3[i];
				vCapacity[i] = temp4[i];
			}
			for (int i = temp1.length; i < size; i++) {
				vSizes[i] = vSize;
			}
		}
		
		keys[capacity] = key;
		values[capacity] = value;
		vSizes[capacity] = vs;
		vCapacity[capacity] = vc;
		
		capacity++;
	}
	
	public void insert(int key, int value) {
		int low = 0;
		int mid = 0;
		int top = capacity - 1;
		
		while (low <= top) {
			mid = (low + top) / 2;
			if (key < keys[mid]) {
				top = mid - 1;
			}
			else if (key > keys[mid]) {
				low = mid + 1;
			}
			else if (key == keys[mid]) {
				this.append(mid, value);
				return;
			}
		}
		
		if (capacity == size) {
			size = 2 * size;
			int[] temp1 = keys;
			keys = new int[size];
			int[][] temp2 = values;
			values = new int[size][];
			int[] temp3 = vSizes;
			vSizes = new int[size];
			int[] temp4 = vCapacity;
			vCapacity = new int[size];
			for (int i = 0; i < temp1.length; i++) {
				keys[i] = temp1[i];
				values[i] = temp2[i];
				vSizes[i] = temp3[i];
				vCapacity[i] = temp4[i];
			}
			for (int i = temp1.length; i < size; i++) {
				vSizes[i] = vSize;
			}
		}
		
		for (int i = capacity; i > low; i--) {
			keys[i] = keys[i - 1];
			values[i] = values[i - 1];
			vSizes[i] = vSizes[i - 1];
			vCapacity[i] = vCapacity[i - 1];
		}
		keys[low] = key;
		values[low] = new int[vSize];
		values[low][0] = value;
		
		capacity++;
		vSizes[low] = vSize;
		vCapacity[low] = 1;
	}
	
	public void append(int pos, int value) {
		if (vCapacity[pos] == vSizes[pos]) {
			vSizes[pos] = 2 * vSizes[pos];
			int[] temp = values[pos];
			values[pos] = new int[vSizes[pos]];
			for (int i = 0; i < temp.length; i++) {
				values[pos][i] = temp[i];
			}
		}
		
		values[pos][vCapacity[pos]] = value;
		vCapacity[pos]++;
	}
	
	public int getCapacity() {
		return capacity;
	}
	
	public int getVCapacity(int key) {
		return vCapacity[key];
	}
	
	public int getVSize(int key) {
		return vSizes[key];
	}
	
	public int get(int index) {
		return keys[index];
	}
	
	public int[] getValue(int index) {
		return values[index];
	}
	
	private int calcSize(int i) {
		int x = 0;
		double y = (double)i;
		do {
			y /= 2;
		}
		while (y > 1.0);
		return 2 ^ x * 10;
	}

}
